

#ifndef UTILS_BLOCKQEUE_H
#define UTILS_BLOCKQEUE_H

#include <queue>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <optional>

template <typename T>
class BlockingQueue
{

private:
    std::queue<T> queue_;               // 底层容器
    mutable std::mutex mutex_;          // 互斥锁（mutable允许const函数修改）
    std::condition_variable not_empty_; // 通知消费者：队列非空
    std::condition_variable not_full_;  // 通知生产者：队列非满
    size_t capacity_;                   // 队列最大容量

public:
    // 构造函数：指定队列容量
    explicit BlockingQueue(size_t capacity) : capacity_(capacity)
    {
        if (capacity == 0)
        {
            throw std::invalid_argument("队列容量不能为0");
        }
    }

    // 禁止拷贝构造和赋值
    BlockingQueue(const BlockingQueue &) = delete;
    BlockingQueue &operator=(const BlockingQueue &) = delete;

    // 入队（阻塞式：队列满时等待）
    void push(const T &item)
    {
        std::unique_lock<std::mutex> lock(mutex_);
        // 等待队列非满（防止虚假唤醒，用while循环）
        not_full_.wait(lock, [this]() { return queue_.size() < capacity_; });
        queue_.push(item);
        lock.unlock();           // 解锁后再通知，减少唤醒等待
        not_empty_.notify_one(); // 通知一个等待的消费者
    }

    // 入队（超时版：队列满时等待指定时间，超时返回false）
    bool try_push(const T &item, std::chrono::milliseconds timeout)
    {
        std::unique_lock<std::mutex> lock(mutex_);
        // 等待超时返回false
        if (!not_full_.wait_for(lock, timeout, [this]() { return queue_.size() < capacity_; }))
        {
            return false;
        }
        queue_.push(item);
        lock.unlock();
        not_empty_.notify_one();
        return true;
    }

    // 出队（阻塞式：队列空时等待）
    T pop()
    {
        std::unique_lock<std::mutex> lock(mutex_);
        // 等待队列非空
        not_empty_.wait(lock, [this]() { return !queue_.empty(); });
        T item = queue_.front();
        queue_.pop();
        lock.unlock();
        not_full_.notify_one(); // 通知一个等待的生产者
        return item;
    }

    // 出队（超时版：队列空时等待指定时间，超时抛出异常）
    T try_pop(std::chrono::milliseconds timeout)
    {
        std::unique_lock<std::mutex> lock(mutex_);
        if (!not_empty_.wait_for(lock, timeout, [this]() { return !queue_.empty(); }))
        {
            throw std::runtime_error("出队超时");
        }
        T item = queue_.front();
        queue_.pop();
        lock.unlock();
        not_full_.notify_one();
        return item;
    }

    // 获取队列当前大小
    size_t size() const
    {
        std::lock_guard<std::mutex> lock(mutex_); // 只读操作也需要加锁
        return queue_.size();
    }

    // 判断队列是否为空
    bool empty() const
    {
        std::lock_guard<std::mutex> lock(mutex_);
        return queue_.empty();
    }

    // 判断队列是否已满
    bool full() const
    {
        std::lock_guard<std::mutex> lock(mutex_);
        return queue_.size() == capacity_;
    }
};

#endif //UTILS_BLOCKQEUE_H
